package com.edais.service.imp;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.edais.domain.Loan;
import com.edais.domain.RateRisesCoupons;
import com.edais.domain.User;
import com.edais.domain.UserInfo;
import com.edais.domain.WeixinMediaBinding;
import com.edais.service.CaptchaService;
import com.edais.service.JkxyService;
import com.edais.service.LoanService;
import com.edais.service.OrderService;
import com.edais.service.RateRisesCouponsService;
import com.edais.service.SMSService;
import com.edais.service.SystemIdWorkerService;
import com.edais.service.UserService;
import com.edais.service.WeixinBindingService;
import com.edais.util.Consts;
import com.edais.util.FtpUtil;
import com.edais.util.LoginRedirectUtil;
import com.edais.util.NumberToCN;
import com.edais.util.StrUtil;
import com.edais.util.weixinAbout.SendWeiXinUtil;
import com.edais.vo.OrderListVo;

import freemarker.template.Configuration;
import freemarker.template.Template;

@Service
public class JkxyServiceImpl implements JkxyService {
	private static final Log logger = LogFactory.getLog(JkxyServiceImpl.class);

	@Autowired
	private UserService userService;

	@Autowired
	private LoanService loanService;

	@Autowired
	private OrderService orderService;

	@Autowired
	private SystemIdWorkerService systemIdWorkerService;

	@Autowired
	private RateRisesCouponsService rateRisesCouponsService;
	@Autowired
	private CaptchaService captchaService;
	@Autowired
	private WeixinBindingService weixinBindingService;
	@Autowired
	private SMSService sMSService;
	
	
	
	

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.edais.service.JkxyService#setJkxy(java.lang.String,
	 * java.util.Map)
	 */
	@Async
	@Override
	@Transactional
	public void setJkxy(String type, Map<String, String> paramsMap)
			throws Exception {
		String logTitle = "订单借款协议生成" + paramsMap.get("orderId");
		logger.info(logTitle + "开始");
		String path = LoginRedirectUtil.agreementPath;
		if(type.equals("loanAgreement")) {
			String orderId = paramsMap.get("orderId");  //订单号码
			if (StringUtils.isBlank(orderId)) {         // 订单号为空
				logger.debug("setJKXY 传入参数为空：订单ID");
				return;
			}else {
				// 获取订单列表信息
				InputStream fileInputStream = null;//文件输入流
				try {
					Map<String,Object> orderMap = new HashMap<String,Object>();
					orderMap.put("orderId", orderId);
					String result = orderService.getOrderFormDetails(orderMap);
					JSONObject jsonObject = JSONObject.fromObject(result);
					if(Consts.SUCCESS_CODE.equals(jsonObject.getString("rescode"))){
						JSONArray jsonArr = jsonObject.getJSONArray("list");
						List<OrderListVo> list = (List)JSONArray.toCollection(jsonArr, OrderListVo.class);  
						if(list != null && list.size() > 0) {
							OrderListVo orderListVo = list.get(0);
							if(orderListVo != null) {
								String investAmount = orderListVo.getInvestAmount(); //投资金额
								String investPeriod = orderListVo.getInvestPeriod(); //投资期限
								String sloanId = orderListVo.getSloanId();           //上架表id
								String userId = orderListVo.getUserId();             //用户ID
								String startDate = orderListVo.getInvestDate();      //起息日期
								String agreementAutoid=orderListVo.getAgreementAutoid();
								String agreementNo=orderListVo.getAgreementNo();
								String assetNo=orderListVo.getAssetNo();
								logger.info("生成协议:agreementAutoid" + agreementAutoid);
								logger.info("生成协议:agreementNo" + agreementNo);
								logger.info("生成协议:assetNo" + assetNo);
								Map<String,String> agrConMap=systemIdWorkerService.getAgreementContext(agreementNo);
								String savePath=agrConMap.get("SAVEPATH");
								logger.info("生成协议:savePath" + savePath);
								Configuration cfg = new Configuration();
								//通过userID获取user信息
								UserInfo userInfo = userService.getUserInfo(userId);
								cfg.setDirectoryForTemplateLoading(new File(path+"/agreement/ftl1/"));  //设置读取模板文件的目录
								//存储数据
								User user = userService.getUserDetail(userId);
								Map<String, Object> maps = new HashMap<String, Object>();  
								if(user != null) {
									if(StringUtils.isNotEmpty(userInfo.getReal_name())) {
										maps.put("name", userInfo.getReal_name());
									}else {
										maps.put("name", "");
									}
									if(StringUtils.isNotEmpty(user.getMobile())) {
										maps.put("phone", user.getMobile());
									}else {
										maps.put("phone", "");
									}
									if(StringUtils.isNotEmpty(userInfo.getId_card())) {
										maps.put("idCard", userInfo.getId_card());
									}else {
										maps.put("idCard", "");
									}
								}else {
									maps.put("name", "");
									maps.put("phone", "");
									maps.put("idCard", "");
								}
								BigDecimal decBuyAmount = new BigDecimal(investAmount);// 购买金额
								maps.put("buyAmount", investAmount); //购买金额
								maps.put("buyAmount_big", NumberToCN.number2CNMontrayUnit(decBuyAmount));
								//获取贷款期限和年华利率
								Map<String, Object> loadMap = new HashMap<String, Object>();
								loadMap.put("sloanId", sloanId);
								Loan loan = loanService.getLoanDetailBySLoanId(loadMap); 

								//获取加息券利率
								Map<String, Object> rateMap = new HashMap<String, Object>();
								rateMap.put("status", "1");
								rateMap.put("orderId", orderId);
								//rateMap.put("productId", "1");
								BigDecimal interest = BigDecimal.ZERO.setScale(2);
								interest = interest.add(loan.getInterest());
								//超享计划的加上加息的利率，其他一律取基准利率
								if(loan.getLoanMonths()==12){
									List<RateRisesCoupons> rateList = rateRisesCouponsService.getAllRateRisesCouponsListByOrderId(rateMap);
									if(rateList != null && rateList.size() > 0) {
										for(RateRisesCoupons rateRisesCoupons : rateList) {
											if(rateRisesCoupons != null) {
												interest = interest.add(rateRisesCoupons.getRate_rises());
											}
										}
									}
								}
								maps.put("interest", interest);
								 if(loan.getRemanDays()==0){
						        	  maps.put("loanMonths", loan.getLoanMonths()+"个月"); 
						        }else{
						        	 maps.put("loanMonths", loan.getRemanDays()+"天"); 
						        }
								//合同有效期
								Scanner sc = new Scanner(System.in); 
								Calendar curr = Calendar.getInstance(); 
								Date date = new SimpleDateFormat("yy-MM-dd").parse(startDate); 
								curr.setTime(date); 
								SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日"); 
								SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd"); 
								curr.set(Calendar.YEAR,curr.get(Calendar.YEAR)+1); 
								Date date2=curr.getTime(); 
								maps.put("valid_start", sdf2.format(sdf3.parse(startDate)));
								maps.put("valid_end", sdf2.format(date2)); 
								//签约时间
								maps.put("newDate", maps.get("valid_start"));
								//获取借款合同
								String re_file_name=agreementNo+".ftl";
								logger.info("生成协议:agreementNo" + agreementAutoid);
								logger.info("生成协议:agreementNoContent" + assetNo);
								maps.put("agreementNo",agreementAutoid); 
							    maps.put("agreementNoContent", assetNo); 
								Template t = cfg.getTemplate(re_file_name);  //读取文件名为Test.ftl的模板
								FileOutputStream fos = new FileOutputStream(
										path+"/agreement/html/"+StrUtil.fileNameMD5(orderId)+".html");
								Writer out = new OutputStreamWriter(fos, "utf-8");  //输出流
								t.process(maps, out); //动态加载root中的数据到Test.html。数据在模板中定义好了。
								out.close();
								fos.close();
								FtpUtil fu = new FtpUtil();
								String fileName = StrUtil.fileNameMD5(orderId)+".html";//文件名称
								String str = null;//文件输入流
								//File f1 = new File(realPath + File.separator + imageFileName);
								File f1 = new File(path+"/agreement/html/"+StrUtil.fileNameMD5(orderId)+".html");
								try {
									fileInputStream = new FileInputStream(f1);
								} catch (FileNotFoundException e) {
									e.printStackTrace();
								} catch (IOException e) {
									e.printStackTrace();
								}
								//1.传入输入流(成功)
								//fu.uploadFileInputStream(fileName,fileInputStream);
								//2.传入字符串
								//str = fu.inputStream2String(fileInputStream);
								//str = fu.inputStream2String2(fileInputStream);
								//fu.uploadString(fileName,str);
								//3.传入字节(成功)
								byte[] in2b= fu.input2byte(fileInputStream);
								String[] arrayStr={userService.getSystemSettingValue(Consts.SystemSettingUpload.FTP_AGREEMENT_URL),
										userService.getSystemSettingValue(Consts.SystemSettingUpload.FTP_AGREEMENT_URL_TWO)
										};
								for (int j = 0; j < arrayStr.length; j++) {
									fu.uploadByteAgreement(fileName,in2b,
											arrayStr[j],
											userService.getSystemSettingValue(Consts.SystemSettingUpload.FTP_AGREEMENT_NAME),
											userService.getSystemSettingValue(Consts.SystemSettingUpload.FTP_AGREEMENT_PWD),
											"/agreement/"+savePath+"/");
								}
							}
						}
					}
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}finally{
					if(null!=fileInputStream){
						fileInputStream.close();
					}
				}
			}
		}
		logger.info(logTitle + "结束");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.edais.service.JkxyService#setJkxyForK(java.lang.String,
	 * java.util.Map)
	 */
	@Async
	@Override
	@Transactional
	public void setJkxyForK(String type, Map<String, String> paramsMap)
			throws Exception {
		String logTitle = "订单借款协议生成" + paramsMap.get("orderId");
		logger.info(logTitle + "开始");
		String path = LoginRedirectUtil.agreementPath;
		if(type.equals("loanAgreement")) {
		    String orderId = paramsMap.get("orderId");  //订单号码
		    String jkxyType=paramsMap.get("jkxyType");//借款协议类型
		    logger.info("借款协议类型："+jkxyType);
			if (StringUtils.isBlank(orderId)) {         // 订单号为空
				logger.debug("setJKXY 传入参数为空：订单ID");
				return;
			}else {
				// 获取订单列表信息
				InputStream fileInputStream = null;//文件输入流
				try {
					Map<String,Object> orderMap = new HashMap<String,Object>();
					orderMap.put("orderId", orderId);
					String result = orderService.getOrderFormDetails(orderMap);
					JSONObject jsonObject = JSONObject.fromObject(result);
					if(Consts.SUCCESS_CODE.equals(jsonObject.getString("rescode"))){
						JSONArray jsonArr = jsonObject.getJSONArray("list");
						List<OrderListVo> list = (List)JSONArray.toCollection(jsonArr, OrderListVo.class);  
						if(list != null && list.size() > 0) {
							OrderListVo orderListVo = list.get(0);
							if(orderListVo != null) {
								String investAmount = orderListVo.getInvestAmount(); //投资金额
								String investPeriod = orderListVo.getInvestPeriod(); //投资期限
								String sloanId = orderListVo.getSloanId();           //上架表id
								String userId = orderListVo.getUserId();             //用户ID
								String startDate = orderListVo.getInvestDate();      //起息日期
								
								Configuration cfg = new Configuration();
								//通过userID获取user信息
								UserInfo userInfo = this.userService.getUserInfo(userId);
								cfg.setDirectoryForTemplateLoading(new File(path+"/agreement/ftl/"));  //设置读取模板文件的目录
								//存储数据
								User user = userService.getUserDetail(userId);
								Map<String, Object> maps = new HashMap<String, Object>();  
								if(user != null) {
									if(StringUtils.isNotEmpty(userInfo.getReal_name())) {
										maps.put("name", userInfo.getReal_name());
									}else {
										maps.put("name", "");
									}
									if(StringUtils.isNotEmpty(user.getMobile())) {
										maps.put("phone", user.getMobile());
									}else {
										maps.put("phone", "");
									}
									if(StringUtils.isNotEmpty(userInfo.getId_card())) {
										maps.put("idCard", userInfo.getId_card());
									}else {
										maps.put("idCard", "");
									}
								}else {
									maps.put("name", "");
									maps.put("phone", "");
									maps.put("idCard", "");
								}
								BigDecimal decBuyAmount = new BigDecimal(investAmount);// 购买金额
								maps.put("buyAmount", investAmount); //购买金额
								maps.put("buyAmount_big", NumberToCN.number2CNMontrayUnit(decBuyAmount));
								logger.info("==========借款协议 购买金额:"+investAmount);
								//获取贷款期限和年华利率
								Map<String, Object> loadMap = new HashMap<String, Object>();
								loadMap.put("sloanId", sloanId);
								Loan loan = this.loanService.getLoanDetailBySLoanId(loadMap); 

								//获取加息券利率
								Map<String, Object> rateMap = new HashMap<String, Object>();
								rateMap.put("status", "1");
								rateMap.put("orderId", orderId);
								//rateMap.put("productId", "1");
								BigDecimal interest = BigDecimal.ZERO.setScale(2);
								interest = interest.add(loan.getInterest());
								List<RateRisesCoupons> rateList = this.rateRisesCouponsService.getAllRateRisesCouponsListByOrderId(rateMap);
								if(rateList != null && rateList.size() > 0) {
									for(RateRisesCoupons rateRisesCoupons : rateList) {
										if(rateRisesCoupons != null) {
											interest = interest.add(rateRisesCoupons.getRate_rises());
										}
									}
								}
								maps.put("interest", interest);
								maps.put("loanMonths", loan.getLoanMonths()); 
								//合同有效期
								Scanner sc = new Scanner(System.in); 
								Calendar curr = Calendar.getInstance(); 
								Date date = new SimpleDateFormat("yy-MM-dd").parse(startDate); 
								curr.setTime(date); 
								SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日"); 
								SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd"); 
								curr.set(Calendar.YEAR,curr.get(Calendar.YEAR)+1); 
								Date date2=curr.getTime(); 
								maps.put("valid_start", sdf2.format(sdf3.parse(startDate)));
								maps.put("valid_end", sdf2.format(date2)); 
								//签约时间
								maps.put("newDate", maps.get("valid_start"));
								//获取借款合同
								//借款合同编号,借款合同内容里面编号
								String no_key="";
								String con_no_key="";
								String re_file_name="loanAgreement_km.ftl";//取K码的特殊模板
					    		if(investAmount==null||"".equals(investAmount)){
					    			investAmount="0.00";
					    		}
					    		String dsje=userService.getSystemSettingValue("key_code_special_amt");	
					    		logger.info("==========借款协议 特殊金额:"+dsje);
					    		if(dsje==null||"".equals(dsje)){
					    			dsje="0.00";
					    		}
					    		//投资金额为80元或者借款协议类型为1  生成虚拟借款协议
					    		if(StringUtils.isBlank(jkxyType)){
					    			if(Double.parseDouble(investAmount)==Double.parseDouble(dsje)){
						    			re_file_name="loanAgreement_km_ts.ftl";
						    		}
					    		}else{
					    			if(jkxyType.equals("1")){
					    				re_file_name="loanAgreement_km_ts.ftl";
					    			}
					    		}
					    		
//					    		if(Double.parseDouble(investAmount)==Double.parseDouble(dsje)||jkxyType.equals("1")){
//					    			re_file_name="loanAgreement_km_ts.ftl";
//					    		}
								if(loan.getLoanMonths()==12){
									no_key=Consts.agreementNo.LOAN_AGREEMENT_NO_12;
									con_no_key=Consts.agreementNo.LOAN_CONTENT_AGREEMENT_NO_12;	
									re_file_name="loanAgreement_12.ftl";
									maps.put("agreementNo", this.userService.getSystemSettingValue(no_key)); 
									maps.put("agreementNoContent", this.userService.getSystemSettingValue(con_no_key));
								}else{
									/*no_key=Consts.agreementNo.LOAN_AGREEMENT_NO_OLD;
									con_no_key=Consts.agreementNo.LOAN_CONTENT_AGREEMENT_NO_OLD;	*/
									String loan_agreement_no="";
									String loan_content_agreement_no="";
									String orderDate=orderListVo.getInvestDate();
									logger.debug("---------------orderDate-----" + orderDate);
						        	try {
										orderDate=(orderDate.replaceAll("-", "")).substring(0,8);
										logger.debug("---------------orderDate-----" + orderDate);
										Map<String, String> reponMap = StrUtil.getAgreementNo(userService, String.valueOf(loan.getLoanMonths()), orderDate);
										if(reponMap!=null){
											loan_agreement_no=reponMap.get("loan_agreement_no");
											loan_content_agreement_no=reponMap.get("loan_content_agreement_no");
										}
									} catch (Exception e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}
						        	logger.debug("---------------loan_agreement_no-----" + loan_agreement_no);
						        	logger.debug("---------------loan_content_agreement_no-----" + loan_content_agreement_no);
						        	maps.put("agreementNo",loan_agreement_no); 
								    maps.put("agreementNoContent", loan_content_agreement_no); 
								}
								Template t = cfg.getTemplate(re_file_name);  //读取文件名为Test.ftl的模板
								FileOutputStream fos = new FileOutputStream(
										path+"/agreement/html/"+StrUtil.fileNameMD5(orderId)+".html");
								Writer out = new OutputStreamWriter(fos, "utf-8");  //输出流
								t.process(maps, out); //动态加载root中的数据到Test.html。数据在模板中定义好了。
								out.close();
								fos.close();
								
								FtpUtil fu = new FtpUtil();
								String fileName = StrUtil.fileNameMD5(orderId)+".html";//文件名称
								String str = null;//文件输入流
								//File f1 = new File(realPath + File.separator + imageFileName);
								File f1 = new File(path+"/agreement/html/"+StrUtil.fileNameMD5(orderId)+".html");
								try {
									fileInputStream = new FileInputStream(f1);
								} catch (FileNotFoundException e) {
									e.printStackTrace();
								} catch (IOException e) {
									e.printStackTrace();
								}
								//1.传入输入流(成功)
								//fu.uploadFileInputStream(fileName,fileInputStream);
								//2.传入字符串
								//str = fu.inputStream2String(fileInputStream);
								//str = fu.inputStream2String2(fileInputStream);
								//fu.uploadString(fileName,str);
								//3.传入字节(成功)
								byte[] in2b= fu.input2byte(fileInputStream);
								String[] arrayStr={this.userService.getSystemSettingValue(Consts.SystemSettingUpload.FTP_AGREEMENT_URL),
										this.userService.getSystemSettingValue(Consts.SystemSettingUpload.FTP_AGREEMENT_URL_TWO)};
								for (int j = 0; j < arrayStr.length; j++) {
									fu.uploadByteAgreement(fileName,in2b,
											arrayStr[j],
											this.userService.getSystemSettingValue(Consts.SystemSettingUpload.FTP_AGREEMENT_NAME),
											this.userService.getSystemSettingValue(Consts.SystemSettingUpload.FTP_AGREEMENT_PWD),
											this.userService.getSystemSettingValue(Consts.SystemSettingUpload.FTP_AGREEMENT_PATH));
								}
							}
						}
					}
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}finally{
					if(null!=fileInputStream){
						fileInputStream.close();
					}
				}
			}
		}
		logger.info(logTitle + "开始");
	}
	
	@Async
	@Transactional
	public void sendMeidaAndSMS(String rescode,String userId,Map<String,String> paramsMap, String finaceId,String buyAmount){
		String logTitle = "推送微信短信" + userId;
		logger.info(logTitle + "开始");
		try{
			if(Consts.SUCCESS_CODE.equals(rescode)){
				//推送购买微信/短信接口
				//封装用户ID
				WeixinMediaBinding mediaBinding = new WeixinMediaBinding();
				mediaBinding.setUserId(Integer.parseInt(userId));
				//先推送微信，微信成功不发短信，失败再发短信
				String mobile = captchaService.getMobileById(userId);//通过用户ID查询使用手机号
				String mediaUid = weixinBindingService.queryMediaUid(mediaBinding);//通过用户ID实体类查询微信标识
				//TODO 逻辑判断
				if(null == mediaUid || "null".equalsIgnoreCase(mediaUid) || "".equalsIgnoreCase(mediaUid)){
					logger.info("[推送短信息]因手机号："+mobile+"并未绑定微信");
					//发送短信
					String cpType="";
					String smsNo="sms02002";//config_sms表中参数
					String tsje=paramsMap.get("buyAmount");
					if (StringUtils.isBlank(userId) 
							|| StringUtils.isBlank(smsNo)|| StringUtils.isBlank(tsje)) {
						logger.debug("deposit/join sendSMS 传入参数为空");
					}
					try{
						// 发送短信
						if(StringUtils.isEmpty(cpType)){
							 sMSService.getSMS(userId,smsNo,tsje);	
						}else{
							sMSService.getSMS(userId,smsNo,tsje,cpType);	
						}
					} catch (Exception e) {
						logger.error("deposit/join sendSMS异常:" + e.getCause(),e);
					}
				}else{
					Map<String,String> weixinTMap = new HashMap<String,String>();
					weixinTMap.put("mediaUid", mediaUid);//微信用户唯一标识 
					String currentShowName=loanService.queryBitShowNameCurrent();//活期
					weixinTMap.put("productInfo", currentShowName);//产品内容
					weixinTMap.put("number", buyAmount);//购买金额
					weixinTMap.put("functionScope", "buy");//购买金额
					
					boolean sendRusult = SendWeiXinUtil.sendWeiXin(weixinTMap);
					if(!sendRusult){
						logger.info("[微信推送失败][推送短信息]因手机号："+mobile+"并未绑定微信或者未关注联币钱包微信号");
						//发送短信
						String cpType="";
						String smsNo="sms02002";//config_sms表中参数
						String tsje=paramsMap.get("buyAmount");
						if (StringUtils.isBlank(userId) 
								|| StringUtils.isBlank(smsNo)|| StringUtils.isBlank(tsje)) {
							logger.debug("deposit/join sendSMS 传入参数为空");
						}
						try{
							// 发送短信
							if(StringUtils.isEmpty(cpType)){
								 sMSService.getSMS(userId,smsNo,tsje);	
							}else{
								sMSService.getSMS(userId,smsNo,tsje,cpType);	
							}
						} catch (Exception e) {
							logger.error("deposit/join sendSMS异常:" + e.getCause());
						}
					}else{
						logger.info("[微信推送]手机号："+mobile+"推送成功");
					}
				}
			}
		}catch (Exception e) {
			logger.error("推送微信或者短信异常",e);
		}
		logger.info(logTitle + "结束");
	}

}